package mxmf.content.meta;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.validation.constraints.NotNull;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import chances.smart.commons.exception.ObjectNotFoundException;
import chances.smart.commons.exception.SmartEagleException;
import mxmf.content.ContentHandler;
import mxmf.content.code.CodeGenerater;
import mxmf.entity.content.Content;
import mxmf.repository.BaseRepository;

@Service
public class ContentMetaService {

    private static final Logger logger = LoggerFactory.getLogger(ContentMetaService.class);

    @Value("${chances.content.meta:file:./config/ContentMeta.json}")
    private Resource resource;// contentMeta文件路径.

    private Map<String, ContentMetaContext<Content>> map;

    private ObjectMapper mapper = new ObjectMapper();

    @Autowired
    private ApplicationContext applicationContext;

    public ContentMetaContext<Content> getByName(@NotNull String name) {
        name = name.toLowerCase();
        ContentMetaContext<Content> contentMeta = map.get(name);
        if (contentMeta == null) {
            throw new ObjectNotFoundException(SmartEagleException.SOURCE_CMS,
                    SmartEagleException.MODULE_CONTENT, "not find contentMeta by name:" + name);
        }
        return contentMeta;
    }

    public ContentMetaContext<Content> getByContent(@NotNull Content content) {
        return this.getByClass(content.getClass());
    }

    public ContentMetaContext<Content> getByClass(@NotNull Class<? extends Content> content) {
        for (ContentMetaContext<Content> context : map.values()) {
            if (context.getT().equals(content)) {
                return context;
            }
        }
        throw new ObjectNotFoundException(SmartEagleException.SOURCE_CMS,
                SmartEagleException.MODULE_CONTENT,
                "not find contentMeta by name:" + content.getCanonicalName());

    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @PostConstruct
    public void init() throws IOException, ClassNotFoundException {
        List<ContentMeta> contentMetaList = null;
        try {

            contentMetaList = mapper.readValue(resource.getInputStream(),
                    new TypeReference<List<ContentMeta>>() {
                    });
        } catch (IOException e) {
            logger.error(e.toString(), e);
            throw e;
        }

        map = new HashMap<>();

        for (ContentMeta meta : contentMetaList) {
            CodeGenerater codeGenerater = (CodeGenerater) applicationContext
                    .getBean(meta.getGeneraterName());
            ContentHandler<Content> contentHandler = (ContentHandler<Content>) applicationContext
                    .getBean(meta.getHandlerName());

            BaseRepository jpaRespository = (BaseRepository) applicationContext
                    .getBean(meta.getRepositoryName());

            String serializeName = meta.getContentMetaSerializeName();

        }

    }

    /**
     * @param resource the resource to set
     */
    public void setResource(Resource resource) {
        this.resource = resource;
    }

}
